# ProcessDetail 进程详情
import json
import traceback
import psutil

from s2c.rules.conf import FIELD_DELIMITER,SYS_CURRENT


# ProcessInfo 进程信息
# dict_type: current | base， current表示用户扫描当前系统，base 基础指纹库
class ProcessInfo:
    def __init__(self, process_id, dict_type=SYS_CURRENT):
        self.pid = process_id
        self.username = None
        self.status = None
        self.exe = None
        self.cmdline = None
        self.full_name = None
        self.name = None
        self.ppid = None
        self.dict_type = dict_type
        self.connections = None
        self.open_files = None

    # 根据pid获取进程信息
    def detail(self):
        try:
            p = psutil.Process(self.pid)
            self.ppid = p.ppid()
            self.full_name = p.name()
            self.name = parse_service_name(p.name())
            self.cmdline = p.cmdline()
            self.status = p.status()
            self.username = p.username()
            self.open_files = []
            files = p.open_files()
            for f in files:
                self.open_files.append(f[0])
            self.connections = p.connections()
            self.exe = p.exe()
        except Exception as e:  # 部分进程的获取 exe 需要root账号
            pass
            # print("Exception(" + str(self.pid) + ") " + repr(e))

    def json(self):
        return {
            'pid': self.pid,
            'ppid': self.ppid,
            'name': self.name,
            'dict_type': self.dict_type,
            'username': self.username,
            'cmdline': self.cmdline,
            'exe': self.exe,
            'status': self.status,
            'open_files': self.open_files,
            'connections': self.connections,
        }

    # 输出 json 格式
    def dump(self):
        obj = self.json()
        print(json.dumps(obj, indent=2, ensure_ascii=True))

    def fields(self):
        return FIELD_DELIMITER.join([
            self.name, str(self.dict_type), self.username or '',
            ' '.join(self.cmdline or []),
                                            self.exe or '', self.status or '',
            str(self.pid), str(self.ppid or '')
        ])


def field_names():
    return FIELD_DELIMITER.join(['name', 'dict_type', 'username', 'cmdline', 'exe', 'status', 'pid', 'ppid'])


# 根据进程名称获取进程名称前面带有/的信息，过滤掉/后面的数据
def parse_service_name(name):
    if name.find('/') == -1:
        return name
    arr = '/'.split(name)
    return arr[0]


if __name__ == "__main__":
    info = ProcessInfo(21447)
    info.detail()
    info.dump()
